package android.Spider;

import java.util.ArrayList;
import java.util.List;

import android.Spider.Questions.Question;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;


public abstract class XmppConnection implements Runnable
{
	public XmppConnection() {}
	
	void Initialize(Activity app)
	{
		m_activity = app;
		SpiderListener.Register(this);
		m_activity.bindService(new Intent(m_activity, SpiderListener.class),
            m_connection, Context.BIND_AUTO_CREATE);
	}
	
	void SendQuestion(ArrayList<String> lstTo, String strQuestion, boolean bAllowForward)
	{
		ArrayList<String> lstOptions = new ArrayList<String>();
		lstOptions.add("Yes");
		lstOptions.add("No");
		
		SendQuestion(lstTo, strQuestion, lstOptions, bAllowForward);
	}
	
	void SendQuestion(ArrayList<String> lstTo, String strQuestion, ArrayList<String> lstOptions, boolean bAllowForward)
	{
		if (m_binder != null)
		{
			if (lstOptions.size() < 2)		// We cannot have a question with less then 2 options. If thats the case, then we convert it to yes/no.
			{
				SendQuestion(lstTo, strQuestion, bAllowForward);
			}
			else
			{
				Question q = Questions.Instance(m_activity).CreateQuestion();
				q.m_bAllowForward = bAllowForward;
				q.m_bAnswered = true;
				q.m_bReceived = false;
				q.m_lstOptions = lstOptions;
				q.m_lstTo = lstTo;
				q.m_strMsg = strQuestion;
				m_binder.SendQuestion(this, q);
			}
		}
	}
	
	void ForwardQuestion(long idQuestion, ArrayList<String> lstTo)
	{
		if (m_binder != null)
			m_binder.ForwardQuestion(idQuestion, lstTo);
	}
	
	void SendAnswer(String strTo, long idQuestion, int nOption)
	{
		if (m_binder != null)
			m_binder.SendAnswer(strTo, idQuestion, nOption);
	}
	
	void SubmitProfile(ProfileUser usrProfile)
	{
		if (m_binder != null)
			m_binder.SubmitProfile(usrProfile);
	}
	
	void RequestAllProfiles()
	{
		if (m_binder != null)
			m_binder.RequestAllProfiles();
	}
	
	void RequestInquiriesResults()
	{
		if (m_binder != null)
			m_binder.RequestInquiriesResults();
	}

	void DeleteInquiry(long idQuestion)
	{
		if (m_binder != null)
			m_binder.DeleteInquiry(idQuestion);
	}
	
	void RequestThreads(int idTopic)
	{
		if (m_binder != null)
			m_binder.RequestThreads(idTopic);
	}

	void SubmitPost(int idThread, String strText)
	{
		if (m_binder != null)
			m_binder.SubmitPost(idThread, strText);
	}

	void CreateTopicThread(int idTopic, String strTitle, String strText)
	{
		if (m_binder != null)
			m_binder.CreateTopicThread(idTopic, strTitle, strText);
	}
	
	void SendPrivateMessage(String strTo, String strText)
	{
		if (m_binder != null)
			m_binder.SendPrivateMessage(strTo, strText);
	}
	
	void Unregister()
	{
		SpiderListener.Unregister(this);
	}
	
	boolean IsInitialized() { return m_binder != null && m_binder.IsInitialized(); }

	private static final int s_nConnected = 0;
	private static final int s_nDisconnected = 1;
	private static final int s_nAnswerSent = 2;
	private static final int s_nQuestionReceived = 3;
	private static final int s_nAnswerReceived = 4;
	private static final int s_nInquiriesReceived = 5;
	private static final int s_nThreadsReceived = 6;
	private static final int s_nMessageReceived = 7;
	private static final int s_nProfilesReceived = 8;
	
	private int m_nAction = -1;
	
	public int m_nArg1;
	public long m_lArg2;
	public Object m_obj1;
	public Object m_obj2;
	
	@SuppressWarnings("unchecked")
	public void run()
	{
		switch (m_nAction)
		{
		case s_nConnected:
			OnConnected();
			break;
		case s_nDisconnected:
			OnDisconnected();
			break;
		case s_nQuestionReceived:
			OnQuestionReceived(m_nArg1, m_lArg2);
			break;
		case s_nAnswerSent:
			OnAnswerSent(m_lArg2);
			break;
		case s_nAnswerReceived:
			OnAnswerReceived(m_lArg2, (String)m_obj1, m_nArg1);
			break;
		case s_nInquiriesReceived:
			OnInquiriesReceived((ArrayList<Integer>)m_obj1, (ArrayList<List<Integer>>)m_obj2);
			break;
		case s_nThreadsReceived:
			OnThreadsReceived((ArrayList<TopicThread>)m_obj1);
			break;
		case s_nMessageReceived:
			OnMessageReceived(m_nArg1);
			break;
		case s_nProfilesReceived:
			OnProfilesReceived((ArrayList<ProfileUser>)m_obj1);
			break;
		}
	}
	
	protected void OnConnected() {}
	protected void OnDisconnected() {}
	protected void OnQuestionReceived(int idRequest, long idQuestion) {}
	protected void OnAnswerSent(long idQuestion) {}
	protected void OnAnswerReceived(long idQuestion, String strSender, int nOption) {}
	protected void OnInquiriesReceived(ArrayList<Integer> lstQuestionID, ArrayList<List<Integer>> lstOptionsCount) {}
	protected void OnThreadsReceived(ArrayList<TopicThread> lstThreads) {}
	protected void OnMessageReceived(int idMessage) {}
	protected void OnProfilesReceived(ArrayList<ProfileUser> lstProfiles) {}


	public final void OnServiceConnected() {
		m_nAction = s_nConnected;
		try {
			m_activity.runOnUIThread(this);
		}
		catch (IllegalArgumentException ex) {
			OnConnected();
		}
	}
	
	public final void OnServiceDisconnected() {
		m_nAction = s_nDisconnected;
		try {
			m_activity.runOnUIThread(this);
		}
		catch (IllegalArgumentException ex) {
			OnDisconnected();
		}
	}
	public final void OnServiceQuestionReceived(int idRequest, long idQuestion) {
		m_nAction = s_nQuestionReceived;
		m_nArg1 = idRequest;
		m_lArg2 = idQuestion;
		try {
			m_activity.runOnUIThread(this);
		}
		catch (IllegalArgumentException ex) {
			OnQuestionReceived(idRequest, idQuestion);
		}
	}

	public final void OnServiceAnswerSent(long idQuestion) {
		m_nAction = s_nAnswerSent;
		m_lArg2 = idQuestion;
		try {
			m_activity.runOnUIThread(this);
		}
		catch (IllegalArgumentException ex) {
			OnAnswerSent(idQuestion);
		}
	}

	public final void OnServiceAnswerReceived(long idQuestion, String strSender, int nOption) {
		m_nAction = s_nAnswerReceived;
		m_nArg1 = nOption;
		m_lArg2 = idQuestion;
		m_obj1 = strSender;
		try {
			m_activity.runOnUIThread(this);
		}
		catch (IllegalArgumentException ex) {
			OnAnswerReceived(idQuestion, strSender, nOption);
		}
	}

	public final void OnServiceInquiriesResults(ArrayList<Integer> lstQuestionID, ArrayList<List<Integer>> lstOptionsCount)
	{
		m_nAction = s_nInquiriesReceived;
		m_obj1 = lstQuestionID;
		m_obj2 = lstOptionsCount;
		try {
			m_activity.runOnUIThread(this);
		}
		catch (IllegalArgumentException ex) {
			OnInquiriesReceived(lstQuestionID, lstOptionsCount);
		}
	}
	
	public final void OnServiceMessageReceived(int idMessage)
	{
		m_nAction = s_nMessageReceived;
		m_nArg1 = idMessage;
		try {
			m_activity.runOnUIThread(this);
		}
		catch (IllegalArgumentException ex) {
			OnMessageReceived(idMessage);
		}
	}
	
	public final void OnServiceProfilesReceived(ArrayList<ProfileUser> lstProfiles)
	{
		m_nAction = s_nProfilesReceived;
		m_obj1 = lstProfiles;
		try {
			m_activity.runOnUIThread(this);
		}
		catch (IllegalArgumentException ex) {
			OnProfilesReceived(lstProfiles);
		}
	}

	public final void OnTopicThreadsResults(ArrayList<TopicThread> lstThreads)
	{
		m_nAction = s_nThreadsReceived;
		m_obj1 = lstThreads;

		try {
			m_activity.runOnUIThread(this);
		}
		catch (IllegalArgumentException ex) {
			OnThreadsReceived(lstThreads);
		}
	}

	private ServiceConnection m_connection = new ServiceConnection()
    {
        public void onServiceConnected(ComponentName className, IBinder service)
        {
    		m_binder = (SpiderListener.SpiderBinder)service;
    		XmppConnection.this.OnServiceConnected();
        }

        public void onServiceDisconnected(ComponentName className)
        {
    		XmppConnection.this.OnServiceDisconnected();
        }
    };

    private Activity m_activity = null;				// Context which holds this connection.
    private SpiderListener.SpiderBinder m_binder;	// Binder to SpiderListener
}
